package token

import (
	"fmt"
	"gin-base/base/db"
	"gin-base/base/rds"
	"gin-base/base/resp"
	"gin-base/common/models/user"
	"github.com/garyburd/redigo/redis"
	"github.com/gin-gonic/gin"
	"strconv"
	"time"
)

type Token struct {
	Value   string
	Expire  string
	UnionId string
}

const KeyPrefixToken = "Token:"
const KeyPrefixUnionIdTokenRelate = "UnionIdTokens:"

//删除unionId下的token
func DeleteTokenByUnionId(unionId string) {
	rds := rds.Open()
	defer rds.Rs.Close()

	res, err := redis.Strings(rds.Rs.Do("SMEMBERS", KeyPrefixUnionIdTokenRelate+unionId))
	if err != nil {
		fmt.Println(err)
	} else {
		for _, value := range res {
			//删除token
			rds.Rs.Do("DEL", KeyPrefixToken+value)
		}

		//删除该unionId集合
		rds.Rs.Do("DEL", KeyPrefixUnionIdTokenRelate+unionId)
	}

}

//创建token与UnionId的关联
func (this *Token) RelateUnionId() bool {
	rds := rds.Open()
	defer rds.Rs.Close()

	if this.UnionId == "" {
		return false
	}

	_, errSet := rds.Rs.Do("SADD", KeyPrefixUnionIdTokenRelate+this.UnionId, this.Value)
	if errSet != nil {
		fmt.Println(errSet)
		return false
	}

	return true
}

//创建token
func (this *Token) Create() bool {
	rds := rds.Open()
	defer rds.Rs.Close()

	_, errSet := rds.Rs.Do("SET", KeyPrefixToken+this.Value, this.UnionId)
	if errSet != nil {
		fmt.Println(errSet)
		return false
	} else {
		expireAt, _ := strconv.ParseInt(this.Expire, 10, 64)
		expireTime := expireAt - time.Now().Unix()
		//设置过期时间
		rds.Rs.Do("EXPIRE", KeyPrefixToken+this.Value, expireTime)
	}

	return true
}

// 返回
func GetUnionIdByToken(token string) (union_id string) {
	rds := rds.Open()
	defer rds.Rs.Close()

	res, err := redis.String(rds.Rs.Do("GET", KeyPrefixToken+token))

	if err != nil {
		return ""
	} else {
		return res
	}
}

// 验证用户凭据，如果凭据有效但未在本系统注册，则自动注册
func AuthToken(token string) bool {
	unionId := GetUnionIdByToken(token)

	if unionId != "" {
		user := user.GetUserByUnionId(unionId)
		if user.ID == 0 {
			//自动创建用户
			db := db.Open()
			defer db.Close()

			user.UnionId = unionId

			db.Create(&user)
		}
		return true
	} else {
		return false
	}
}

/**
中间件
*/

func SetUser() gin.HandlerFunc {
	return func(c *gin.Context) {
		var userOne user.User

		access_token := GetTokenFromHeader(c)

		if len(access_token) != 0 {
			if AuthToken(access_token) {
				//验证通过，设置用户信息
				unionId := GetUnionIdByToken(access_token)
				userOne = user.GetUserByUnionId(unionId)
			}

			c.Set("user", &userOne)
		}

		c.Next()
	}
}

func MustUser() gin.HandlerFunc {
	return func(c *gin.Context) {
		user := User(c)
		switch {
		case user == nil || user.ID == 0:
			data := resp.GetInfo("AUTH", "")

			var responseData = make(map[string]interface{})
			responseData["code"] = data.Code
			responseData["status"] = data.Status
			responseData["message"] = data.Message
			responseData["data"] = data.Data

			c.JSON(data.Status, responseData)
			c.Abort()
		default:
			c.Next()
		}
	}
}

func User(c *gin.Context) *user.User {
	v, ok := c.Get("user")
	if !ok {
		return nil
	}
	u, ok := v.(*user.User)
	if !ok {
		return nil
	}
	return u
}
